#!/bin/bash#########################
#                                  # #
#           !htlogparse!           #   #
#                                  #     #
#   ~~~~~~~~~~Ver. 1~~~~~~~~~~~    #_______#
# This script is meant to make parsing the #
# Apache access logs for common and useful #
# information much easier.  -- Gary Locke  #
############################################



# Mad style, yo.
RED="\033[1;31m"
GREEN="\033[1;32m"
COLOR_RESET="\033[0m"
BOLD=`tput bold`
NORMAL=`tput sgr0`

# Also important.
LOG=$1

# wat do
options() {
printf "\nOptions:\n\n"
printf "${BOLD}1)${NORMAL} IPs by visits\t"
printf "${BOLD}2)${NORMAL} IPs by traffic\n"
printf "${BOLD}3)${NORMAL} Traffic by date\t"
printf "${BOLD}4)${NORMAL} Traffic by total\n"
printf "${BOLD}5)${NORMAL} Popular requests\t"
printf "${BOLD}6)${NORMAL} Total hits\n"
printf "${BOLD}7)${NORMAL} Active users\t\t"
printf "${BOLD}${RED}8)${NORMAL}${RED} Popular user agents${COLOR_RESET}\n\n"
read -e -p "Select an option: " OPT
}

# Function junction.
getfile() {
read -e -p "Enter path to log file: " LOG
}

ip_by_freq() {
awk '{print $1}' $LOG|sort -n|uniq -c|sort -n
}

ip_by_data() {
 for ip in `awk '{print $1}' $LOG|sort -n|uniq`;do data=`grep $ip $LOG|awk '{sum+=$10} END {print sum/1048576}'`;printf "${data}MB\t${ip}\n";done|sort -n
}

data_by_date() {
for log_date in `awk '{print $4}' $LOG|awk -F':' '{print $1}'|sed 's/\[//'|uniq`;do data=`grep $log_date $LOG|awk '{sum+=$10} END {print sum/1048576}'`;printf "${data}MB\t${log_date}\n";done
printf "\n${BOLD}${RED}Use option '4' to sort by download totals.${COLOR_RESET}${NORMAL}\n"
}

data_by_total() {
for log_date in `awk '{print $4}' $LOG|awk -F':' '{print $1}'|sed 's/\[//'|uniq`;do data=`grep $log_date $LOG|awk '{sum+=$10} END {print sum/1048576}'`;printf "${data}MB\t${log_date}\n";done|sort -n
printf "\n${BOLD}${RED}Use option '3' to sort by date.${COLOR_RESET}${NORMAL}\n"
}

popular_files() {
for filename in `awk '{print $7}' $LOG|sort|uniq|grep -v '%'`;do count=`grep -cw "${filename}" $LOG`;printf "${count}\t${filename}\n";done|sort -n
omitted=`awk '{print $7}' $LOG|grep -c '%'`
if [[ ! "$omitted" == 0 ]];then
echo -e "\n${BOLD}${RED}${omitted} files contained '%' and were omitted.${NORMAL}${COLOR_RESET}\n"
fi
}

total_hits() {
hits=`awk '{print $6}' $LOG|grep GET|wc -l`
echo -e "Total hits: ${hits}\n"
}

active_users() {
awk '{print $3}' $LOG|sed 's/^\-$/(no user)/'|sort|uniq -c|sort -n
printf "\n"
}

user_agents() {
awk -F'\"' '{print $(NF-1)}' $LOG|sort|uniq|while read agent;do count=`grep -cw "${agent}" $LOG`;printf "${count}\t${agent}\n";done|sort -n
}

# Stuffs.
if [[ -z "$LOG" ]]; then
        echo -e "${BOLD}You didn't specify an access log.${NORMAL}"
        getfile
        if [[ -z "$LOG" ]]; then
                echo -e "${BOLD}${RED}Forget it!${COLOR_RESET}${NORMAL}\n"
                exit 1
        fi
fi

if [[ ! -f "$LOG" ]]; then
        echo -e "${BOLD}${RED}Not a file!${COLOR_RESET}${NORMAL}\n"
        exit 1
fi

if [[ ! -r "$LOG" ]]; then
        echo -e "${BOLD}${RED}Unreadable file!${COLOR_RESET}${NORMAL}\n"
        exit 1
fi

LOG_SIZE=`stat -c%s $LOG`
if [[ "$LOG_SIZE" -gt 50000000 ]]; then
        echo -e "${RED}WARNING: Big file! This might take a while.${COLOR_RESET}\n"
fi

options
if [[ -z "$OPT" ]]; then
        printf "\n${RED}You must specify an option!\n${COLOR_RESET}"
        options
        if [[ -z "$OPT" ]]; then
                printf "\nYou must not ${BOLD}want${NORMAL} my help!\n"
                exit 1
        fi
fi

printf "\nWait for it...\n\n"

# Options!
case $OPT in
        1) ip_by_freq && exit 0;;
        2) ip_by_data && exit 0;;
        3) data_by_date && exit 0;;
        4) data_by_total && exit 0;;
        5) popular_files && exit 0;;
        6) total_hits && exit 0;;
        7) active_users && exit 0;;
        8) user_agents && exit 0;;
        *) help && exit 0;;
esac

echo -e "If you can read this, ${BOLD}panic!${NORMAL}\n"
exit 1
